var gulp = require('gulp');

var options = {
	watch: false,
	product: false
};
if ('product' == process.argv[2]) {
	options.watch = false;
	options.product = true;
}
if ('serve' == process.argv[2]) {
	options.watch = true;
	options.product = false;
}

gulp.task('clean', function() {
	var del = require('del');
	return del(['dist/**', '!dist']);
});

gulp.task('copy.vendor', function() {
	var concat = require('gulp-concat');
	var cleanCSS = require('gulp-clean-css');
	var rename = require('gulp-rename');
	var uglify = require('gulp-uglify');
	var gulpif = require('gulp-if');
	var merge = require('merge2');

	var pipeCss = gulp.src(['node_modules/bootstrap/dist/css/bootstrap.css',
		'node_modules/cropper/dist/cropper.css'])
		.pipe(concat('vendor.css'))
		.pipe(gulp.dest('dist/assets/css'))
		.pipe(rename('vendor.min.css'))
		.pipe(gulpif(options.product, cleanCSS()))
		.pipe(gulp.dest('dist/assets/css'));

	var pipeFonts = gulp.src(['node_modules/bootstrap/dist/fonts/*.*'])
		.pipe(gulp.dest('dist/assets/fonts'));

	var pipeJs = gulp.src([
		// 'node_modules/es6-shim/es6-shim.js',
		'node_modules/jquery/dist/jquery.js',
		'node_modules/bootstrap/dist/js/bootstrap.js',
		'node_modules/cropper/dist/cropper.js',
		'node_modules/angular2/bundles/angular2-polyfills.js',
	])
		.pipe(concat('vendor.js'))
		.pipe(gulp.dest('dist/assets/js'))
		.pipe(rename('vendor.min.js'))
		.pipe(gulpif(options.product, uglify({ mangle: false })))
		.pipe(gulp.dest('dist/assets/js'));

	return merge([pipeCss, pipeFonts, pipeJs]);
});

gulp.task('copy.assets', function() {
	var connect = require('gulp-connect');
	return gulp.src([
		'index.html',
		'app/**/*.*',
		'!app/**/*.ts',
		'!app/**/*.scss',
		'assets/**/*.*'
	], { base: '.' })
		.pipe(gulp.dest('dist'))
		.pipe(connect.reload());
});

gulp.task('sass', function() {
	var sass = require('gulp-sass');
	var autoprefixer = require('gulp-autoprefixer');
	var cleanCSS = require('gulp-clean-css');
	var rename = require('gulp-rename');
	var gulpif = require('gulp-if');
	var connect = require('gulp-connect');

	return gulp.src('app/app.scss')
		.pipe(sass({
			// includePaths: ['']
		}).on('error', sass.logError))
		.pipe(autoprefixer({
			browsers: [
				'last 2 versions',
				'iOS >= 7',
				'Android >= 4',
				'Explorer >= 10',
				'ExplorerMobile >= 11'
			],
			cascade: false
		}))
		.pipe(rename('bundle.css'))
		.pipe(gulp.dest('dist/assets/css'))
		.pipe(rename('bundle.min.css'))
		.pipe(gulpif(options.product, cleanCSS()))
		.pipe(gulp.dest('dist/assets/css'))
		.pipe(connect.reload());
});

gulp.task('browerify', function() {
	var browserify = require('browserify');
	var watchify = require('watchify');
	var tsify = require('tsify');
	var source = require('vinyl-source-stream');
	var buffer = require('vinyl-buffer');
	var uglify = require('gulp-uglify');
	var gutil = require('gulp-util');
	var rename = require('gulp-rename');
	var gulpif = require('gulp-if');
	var connect = require('gulp-connect');

	var b = browserify(['./app/boot.ts', './typings/tsd.d.ts'], { debug: true })
		.plugin(tsify, { noImplicitAny: true });

	if (options.watch) {
		b = watchify(b, {});
		b.on('update', bundle);
		b.on('log', gutil.log);
	}

	return bundle();

	function bundle() {
		return b.bundle()
			.on('error', gutil.log)
			//Pass desired output filename to vinyl-source-stream
			.pipe(source('bundle.js'))
			.pipe(gulp.dest('dist/assets/js'))
			// optional, remove if you don't need to buffer file contents
			.pipe(buffer())
			.pipe(rename('bundle.min.js'))
			.pipe(gulpif(options.product, uglify({ mangle: false })))
			// Start piping stream to tasks!
			.pipe(gulp.dest('dist/assets/js'))
			.pipe(connect.reload());
	}
});

gulp.task('webpack', function(done) {
	var path = require('path');
	var webpack = require('webpack');
	var uglify = require('gulp-uglify');
	var rename = require('gulp-rename');
	var gulpif = require('gulp-if');
	var connect = require('gulp-connect');
	// var gutil = require('gulp-util');

	function webpackCallback(err, stats) {
		function outputStats() {
			// print build stats and errors
			console.log(stats.toString({
				'colors': true,
				'modules': false,
				'chunks': false,
				// 'exclude': ['node_modules']
			}));

			if (done) {
				done();
				done = undefined;
			}
		}
		if (!err) {
			gulp.src(['dist/assets/js/bundle.js'])
				.pipe(rename('bundle.min.js'))
				.pipe(gulpif(options.product, uglify({ mangle: false })))
				.pipe(gulp.dest('dist/assets/js'))
				.on('end', function() {
					outputStats();
				}).pipe(connect.reload());
		} else {
			outputStats();
		}
	}

	var compiler = webpack({
		entry: './app/boot.ts',
		output: {
			path: path.resolve('dist/assets/js'),
			filename: 'bundle.js',
			pathinfo: false // show module paths in the bundle, handy for debugging
		},
		devtool: 'source-map',
		module: {
			loaders: [{
				test: /\.ts$/,
				loader: 'awesome-typescript',
				query: {
					'doTypeCheck': false,
				},
				include: path.resolve('app'),
				exclude: /node_modules/
			}, {
					test: /\.js$/,
					include: path.resolve('node_modules/angular2'),
					loader: 'strip-sourcemap'
				}]
		},
		resolve: {
			extensions: ["", ".js", ".ts"]
		}
	});

	if (options.watch) {
		compiler.watch(null, webpackCallback);
	} else {
		compiler.run(webpackCallback);
	}
});

gulp.task('build', ['copy.vendor', 'copy.assets', 'sass', 'webpack']);
gulp.task('product', ['build'], () => {
	var pkg = require('./package.json');
	var replace = require('gulp-replace');
	var moment = require("moment");
	
	var dateStr = moment().format("YYYYMMDDHHmmss");
	var ver = pkg.version + '.' + dateStr;

	return gulp.src(['dist/index.html'])
		.pipe(replace(/\$VERSION/g, ver))
		.pipe(gulp.dest('dist'));
});

gulp.task('serve', ['build'], function(done) {
	gulp.watch(['index.html', 'app/**/*.html'], ['copy.assets']);
	gulp.watch(['app/**/*.scss'], ['sass']);

	var connect = require('gulp-connect');
	connect.server({
		port: 5000,
		root: 'dist',
		livereload: {
			port: 35720
		}
	});
});